package fem2.analysis;

import math2.FunctionRnToR;
import math2.MathUtilities;
import math2.PiecewiseLinearFunctionRToR;
import fem2.Constraint;
import fem2.Model;
import fem2.strategies.NonAdaptiveNewtonRaphsonStrategy;

/**
 * Perform static or quasi static analysis<br>
 * Note: this analysis will modify time factor at load and constraint to achieve
 * result. Su use it with case with dynamics analysis
 * 
 * @author hbui
 * 
 */
public class NonlinearStaticManualAnalysis extends Analysis {

	public NonlinearStaticManualAnalysis(Model m, double[] tArray, double[] lambdaArray) {
		super(m);
		if (tArray.length != lambdaArray.length) {
			throw new Error("tArray and lambdaArray must be of the same length");
		}
		setStrategy(new NonAdaptiveNewtonRaphsonStrategy(m, tArray));
		/*
		 * initialize load and costraint
		 */
		initializeLoadAndConstraint(tArray, lambdaArray);
	}

	public NonlinearStaticManualAnalysis(Model m, double[] lambdaArray) {
		super(m);
		int nt = lambdaArray.length;
		setStrategy(new NonAdaptiveNewtonRaphsonStrategy(m, nt));
		/*
		 * create lambda
		 */
		double[] tArray = MathUtilities.createLambdaArray(1.0, 1.0, nt);
		/*
		 * initialize load and costraint
		 */
		initializeLoadAndConstraint(tArray, lambdaArray);
	}

	/**
	 * @param tArray
	 * @param lambdaArray
	 */
	private void initializeLoadAndConstraint(double[] tArray, double[] lambdaArray) {
		/*
		 * create lambda
		 */
		FunctionRnToR lambda = new PiecewiseLinearFunctionRToR(tArray, lambdaArray);
		/*
		 * set time factor for all the load
		 */
		for (int i = 0; i < getModel().countLoads(); i++) {
			getModel().getLoad(i).setTimeFactor(lambda);
		}
		/*
		 * set time factor for all the constraint
		 */
		for (int i = 0; i < getModel().getMesh().countNodes(); i++) {
			Constraint c = getModel().getMesh().getNode(i).getConstraint();
			if (c != null) {
				c.setTimeFactor(lambda);
			}
		}
	}

}
